using Microsoft.AspNetCore.SignalR.Client;
using MultiAgentsClient.ChatDataStructures;
using MultiAgentsClient.Manager.DataModel;
using MultiAgentsClient.Service.WorkflowEngine.BuiltInNodes;
using MultiAgentsShared;
using static MultiAgentsClient.Manager.SystematicNotificationManager;
using static MultiAgentsClient.Manager.WorkflowManager;

namespace MultiAgentsClient.Service.SignalRService;

public class SignalRWorkflowService : SignalRClientServiceBase
{
    private readonly SystemConfigDataModel systemConfigDataModel;
    private readonly UserDataModel userDataModel;

    public enum ApiRequestType
    {
        SendSessionId,
        SubscriptonUserRequest,
        LlmNodeRequest,
        GetAllWorkflowsByUserRequest,
        WorkflowProccessedRequest,
        CreateNewWorkflowRequest,
        UpdateWorkflowRequest,
        RemoveWorkflowRequest,
        ShareWorkflowRequest,
        LoadWorkflowByShareCodeRequest,
        LLMSwitchNodeRequest,
        ParameterExtractionNodeRequest,
    }

    public SignalRWorkflowService(SystemConfigDataModel systemConfigDataModel, UserDataModel userDataModel) : base("WorkflowHub")
    {
        this.systemConfigDataModel = systemConfigDataModel;
        this.userDataModel = userDataModel;

        eventBus.Subscribe<SessionStartCommand>(cmd => { Task.Run(() => SendSessionId(cmd)); });
    }

    protected override async Task OnConnectCompleted()
    {
        await SendSessionId(new SessionStartCommand(systemConfigDataModel.sessionId, userDataModel.Id));
    }

    private async Task SendSessionId(SessionStartCommand cmd)
    {
        if (cmd.SessionId == "")
        {
            return;
        }

        await SendSignalRRequest(ApiRequestType.SendSessionId.ToString(), new Dictionary<string, object>()
            {
                { "sessionId", cmd.SessionId },
                { "userId", cmd.UserId },
            });
    }

    protected override void HubMethodRegistration()
    {
        //Node
        hubConnection.On<string, string>("LlmNodeResponse", LlmNodeResponse);

        //WorkflowConfig
        hubConnection.On<int, int, string, string>("CreateNewWorkflowResponse", CreateNewWorkflowResponse);
        hubConnection.On<int, int, string, string>("UpdateWorkflowResponse", UpdateWorkflowResponse);
        hubConnection.On<int>("RemoveWorkflowResponse", RemoveWorkflowResponse);
        hubConnection.On<List<string>>("GetAllWorkflowResponse", GetAllWorkflowResponse);
        hubConnection.On<List<string>>("RecieveSystematicNotification", RecieveSystematicNotification);
        hubConnection.On<string, string>("NodeLLMSwitchApiResponse", NodeLLMSwitchApiResponse);
        hubConnection.On<string, List<string>>("NodeParameterExtractionApiResponse", NodeParameterExtractionApiResponse);
    }

    private void LlmNodeResponse(string nodeId, string llmResponse)
    {
        eventBus.Publish(new NodeLlmResponse(nodeId)
        {
            llmResult = llmResponse
        });
    }

    private void GetAllWorkflowResponse(List<string> workflowsJSON)
    {
        List<Workflow> workflows = workflowsJSON.Select(workflowjson => SerializableObjectBase.FromJson<Workflow>(workflowjson)).ToList();

        eventBus.Publish(new GetAllWorkflowResponseCommand(workflows));
    }

    private void CreateNewWorkflowResponse(int workflowId, int userId, string workflowName, string workflowJson)
    {
        eventBus.Publish(new CreateNewWorkflowResponseCommand(workflowId, userId, workflowName, workflowJson));
    }

    private void UpdateWorkflowResponse(int workflowId, int ownerId, string workflowName, string workflowJson)
    {
        eventBus.Publish(new UpdateWorkflowResponseCommand(workflowId, ownerId, workflowName, workflowJson));
    }

    private void RemoveWorkflowResponse(int workflowId)
    {
        eventBus.Publish(new RemoveWorkflowResponseCommand(workflowId));
    }

    private void RecieveSystematicNotification(List<string> notificationsListJson)
    {
        List<WorkflowNotification> notifications = notificationsListJson.Select(notificationjson => SerializableObjectBase.FromJson<WorkflowNotification>(notificationjson)).ToList();
        eventBus.Publish(new RecieveSystematicNotificationCommand(notifications));
    }

    private void NodeLLMSwitchApiResponse(string nodeId, string className)
    {
        eventBus.Publish(new NodeLLMSwitchResponse(nodeId)
        {
            SwitchResult = className,
        });
    }

    private void NodeParameterExtractionApiResponse(string nodeId, List<string> values)
    {
        eventBus.Publish(new NodeParameterExtractionResponse(nodeId)
        {
            ParameterValues = values,
        });
    }
}
